0400 // Routines to let C code use special x86 instructions.
0401 
0402 static inline uchar
0403 inb(ushort port)
0404 {
0405   uchar data;
0406 
0407   asm volatile("in %1,%0" : "=a" (data) : "d" (port));
0408   return data;
0409 }
0410 
0411 static inline void
0412 insl(int port, void *addr, int cnt)
0413 {
0414   asm volatile("cld; rep insl" :
0415                "=D" (addr), "=c" (cnt) :
0416                "d" (port), "0" (addr), "1" (cnt) :
0417                "memory", "cc");
0418 }
0419 
0420 static inline void
0421 outb(ushort port, uchar data)
0422 {
0423   asm volatile("out %0,%1" : : "a" (data), "d" (port));
0424 }
0425 
0426 static inline void
0427 outw(ushort port, ushort data)
0428 {
0429   asm volatile("out %0,%1" : : "a" (data), "d" (port));
0430 }
0431 
0432 static inline void
0433 outsl(int port, const void *addr, int cnt)
0434 {
0435   asm volatile("cld; rep outsl" :
0436                "=S" (addr), "=c" (cnt) :
0437                "d" (port), "0" (addr), "1" (cnt) :
0438                "cc");
0439 }
0440 
0441 static inline void
0442 stosb(void *addr, int data, int cnt)
0443 {
0444   asm volatile("cld; rep stosb" :
0445                "=D" (addr), "=c" (cnt) :
0446                "0" (addr), "1" (cnt), "a" (data) :
0447                "memory", "cc");
0448 }
0449 
0450 struct segdesc;
0451 
0452 static inline void
0453 lgdt(struct segdesc *p, int size)
0454 {
0455   volatile ushort pd[3];
0456 
0457   pd[0] = size-1;
0458   pd[1] = (uint)p;
0459   pd[2] = (uint)p >> 16;
0460 
0461   asm volatile("lgdt (%0)" : : "r" (pd));
0462 }
0463 
0464 struct gatedesc;
0465 
0466 static inline void
0467 lidt(struct gatedesc *p, int size)
0468 {
0469   volatile ushort pd[3];
0470 
0471   pd[0] = size-1;
0472   pd[1] = (uint)p;
0473   pd[2] = (uint)p >> 16;
0474 
0475   asm volatile("lidt (%0)" : : "r" (pd));
0476 }
0477 
0478 static inline void
0479 ltr(ushort sel)
0480 {
0481   asm volatile("ltr %0" : : "r" (sel));
0482 }
0483 
0484 static inline uint
0485 readeflags(void)
0486 {
0487   uint eflags;
0488   asm volatile("pushfl; popl %0" : "=r" (eflags));
0489   return eflags;
0490 }
0491 
0492 static inline void
0493 loadgs(ushort v)
0494 {
0495   asm volatile("movw %0, %%gs" : : "r" (v));
0496 }
0497 
0498 
0499 
0500 static inline uint
0501 rebp(void)
0502 {
0503   uint val;
0504   asm volatile("movl %%ebp,%0" : "=r" (val));
0505   return val;
0506 }
0507 
0508 static inline uint
0509 resp(void)
0510 {
0511   uint val;
0512   asm volatile("movl %%esp,%0" : "=r" (val));
0513   return val;
0514 }
0515 
0516 static inline void
0517 cli(void)
0518 {
0519   asm volatile("cli");
0520 }
0521 
0522 static inline void
0523 sti(void)
0524 {
0525   asm volatile("sti");
0526 }
0527 
0528 static inline uint
0529 xchg(volatile uint *addr, uint newval)
0530 {
0531   uint result;
0532 
0533   // The + in "+m" denotes a read-modify-write operand.
0534   asm volatile("lock; xchgl %0, %1" :
0535                "+m" (*addr), "=a" (result) :
0536                "1" (newval) :
0537                "cc");
0538   return result;
0539 }
0540 
0541 static inline void
0542 lcr0(uint val)
0543 {
0544   asm volatile("movl %0,%%cr0" : : "r" (val));
0545 }
0546 
0547 
0548 
0549 
0550 static inline uint
0551 rcr0(void)
0552 {
0553   uint val;
0554   asm volatile("movl %%cr0,%0" : "=r" (val));
0555   return val;
0556 }
0557 
0558 static inline uint
0559 rcr2(void)
0560 {
0561   uint val;
0562   asm volatile("movl %%cr2,%0" : "=r" (val));
0563   return val;
0564 }
0565 
0566 static inline void
0567 lcr3(uint val)
0568 {
0569   asm volatile("movl %0,%%cr3" : : "r" (val));
0570 }
0571 
0572 static inline uint
0573 rcr3(void)
0574 {
0575   uint val;
0576   asm volatile("movl %%cr3,%0" : "=r" (val));
0577   return val;
0578 }
0579 
0580 // Layout of the trap frame built on the stack by the
0581 // hardware and by trapasm.S, and passed to trap().
0582 struct trapframe {
0583   // registers as pushed by pusha
0584   uint edi;
0585   uint esi;
0586   uint ebp;
0587   uint oesp;      // useless & ignored
0588   uint ebx;
0589   uint edx;
0590   uint ecx;
0591   uint eax;
0592 
0593   // rest of trap frame
0594   ushort gs;
0595   ushort padding1;
0596   ushort fs;
0597   ushort padding2;
0598   ushort es;
0599   ushort padding3;
0600   ushort ds;
0601   ushort padding4;
0602   uint trapno;
0603 
0604   // below here defined by x86 hardware
0605   uint err;
0606   uint eip;
0607   ushort cs;
0608   ushort padding5;
0609   uint eflags;
0610 
0611   // below here only when crossing rings, such as from user to kernel
0612   uint esp;
0613   ushort ss;
0614   ushort padding6;
0615 };
0616 
0617 
0618 
0619 
0620 
0621 
0622 
0623 
0624 
0625 
0626 
0627 
0628 
0629 
0630 
0631 
0632 
0633 
0634 
0635 
0636 
0637 
0638 
0639 
0640 
0641 
0642 
0643 
0644 
0645 
0646 
0647 
0648 
0649 
